package com.smedi.ismedi.web.starter.config;

import com.smedi.ismedi.authority.starter.common.ResponseData;
import com.smedi.ismedi.authority.starter.constant.AuthorityConstant;
import com.smedi.ismedi.web.starter.property.SwaggerProperty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestParameterBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.RequestParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.ApiSelectorBuilder;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Configuration
@EnableSwagger2
@RequiredArgsConstructor
public class SwaggerConfig {
    private final SwaggerProperty swaggerProperty;

    /**
     * 获取api基本信息
     *
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title(swaggerProperty.getTitle())
                .description(swaggerProperty.getDescription())
                .contact(new Contact(swaggerProperty.getAuthor(), swaggerProperty.getUrl(), swaggerProperty.getEmail()))
                .version(swaggerProperty.getVersion())
                .build();
    }

    /**
     * 创建头请求参数配置
     *
     * @param name
     * @param required
     * @return
     */
    private RequestParameter getHeaderParameter(String name, boolean required) {
        return new RequestParameterBuilder()
                .name(name)
                .description(name)
                .required(required)
                .in("header")
                .accepts(Collections.singleton(MediaType.APPLICATION_JSON))
                .build();
    }

    @Bean
    public Docket api() {
        log.info("配置Swagger");

        // 配置头信息
        List<RequestParameter> pars = new ArrayList<RequestParameter>();
        pars.add(getHeaderParameter(AuthorityConstant.ISMEDI_ACCESS_TOKEN, false));

        // 配置额外头参数信息
        if (swaggerProperty.getHeaders() != null) {
            for (String str : swaggerProperty.getHeaders()) {
                String header = "";
                boolean required = false;
                if (str.indexOf(":") > 0) {
                    header = str.substring(0, str.lastIndexOf(":"));
                    required = Boolean.valueOf(str.substring(str.lastIndexOf(":") + 1));
                } else {
                    header = str;
                }
                pars.add(getHeaderParameter(header, required));
            }
        }

        // 创建配置文件
        ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(this.apiInfo())
                .forCodeGeneration(true)
                .genericModelSubstitutes(ResponseData.class)
                .pathMapping("/")
                .select(); // 选择那些路径和api会生成document

        // 配置扫描包的的文件
        String packages = "";
        if (swaggerProperty.getScanPackages() != null) {
            for (String path : swaggerProperty.getScanPackages()) {
                packages += path + ",";
            }
            if (!StringUtils.isEmpty(packages)) packages = packages.substring(0, packages.length() - 1);
        }

        return builder.apis(RequestHandlerSelectors.basePackage(packages))// 对自身api开放
                .paths(PathSelectors.regex("(?!/error.*).*"))// 错误路径不监控
                .build().globalRequestParameters(pars).enable(swaggerProperty.isEnabled());
    }
}
